import 'dart:convert';

class CryptoUtils {
  // RC4 加密/解密核心
  static List<int> _rc4(List<int> input, String key) {
    List<int> s = List<int>.generate(256, (i) => i);
    List<int> k =
        List<int>.generate(256, (i) => key.codeUnitAt(i % key.length));

    int j = 0;
    for (int i = 0; i < 256; i++) {
      j = (j + s[i] + k[i]) % 256;
      _swap(s, i, j);
    }

    int i = 0;
    j = 0;
    List<int> output = [];
    for (int n = 0; n < input.length; n++) {
      i = (i + 1) % 256;
      j = (j + s[i]) % 256;
      _swap(s, i, j);
      int t = (s[i] + s[j]) % 256;
      output.add(input[n] ^ s[t] ^ 0x55);
    }
    return output;
  }

  // Base64 自定义字符集
  static const List<String> _base64Chars = [
    '!',
    '@',
    '#',
    '\$',
    '%',
    '^',
    '&',
    '*',
    '(',
    ')',
    '_',
    '+',
    '{',
    '}',
    '[',
    ']',
    '|',
    'A',
    ';',
    ':',
    'D',
    'B',
    '<',
    '>',
    ',',
    '.',
    '?',
    'C',
    '0',
    '1',
    '2',
    '3',
    '4',
    '5',
    '6',
    '7',
    '8',
    '9',
    'a',
    'b',
    'c',
    'd',
    'e',
    'f',
    'g',
    'h',
    'i',
    'j',
    'k',
    'l',
    'm',
    'n',
    'o',
    'p',
    'q',
    'r',
    's',
    't',
    'u',
    'v',
    'w',
    'x',
    'y',
    'z'
  ];

  // 工具方法：交换列表元素
  static void _swap(List<int> list, int i, int j) {
    int temp = list[i];
    list[i] = list[j];
    list[j] = temp;
  }

  // 加密并Base64编码
  static String encryptAndBase64Encode(String key, String plaintext) {
    List<int> bytes = utf8.encode(plaintext);
    List<int> encrypted = _rc4(bytes, key);
    return _base64Encode(encrypted);
  }

  // Base64解码并解密
  static String base64DecodeAndDecrypt(String key, String encodedCiphertext) {
    List<int> decoded = _base64Decode(encodedCiphertext);
    List<int> decrypted = _rc4(decoded, key);
    // print('$decrypted======数据decrypted');
    return _safeUtf8Decode(decrypted);
  }

  // 自定义Base64编码
  static String _base64Encode(List<int> data) {
    final buffer = StringBuffer();
    int i = 0;
    while (i < data.length) {
      int octetA = i < data.length ? data[i++] : 0;
      int octetB = i < data.length ? data[i++] : 0;
      int octetC = i < data.length ? data[i++] : 0;

      int triple = (octetA << 16) | (octetB << 8) | octetC;

      buffer.write(_base64Chars[(triple >> 18) & 0x3F]);
      buffer.write(_base64Chars[(triple >> 12) & 0x3F]);
      buffer.write(_base64Chars[(triple >> 6) & 0x3F]);
      buffer.write(_base64Chars[triple & 0x3F]);
    }

    int padding = (3 - (data.length % 3)) % 3;
    return buffer.toString().substring(0, buffer.length - padding) +
        ('=' * padding);
  }

  // 自定义Base64解码
  static List<int> _base64Decode(String data) {
    final Map<String, int> charMap = {};
    
    for (var i = 0; i < _base64Chars.length; i++) {
      charMap[_base64Chars[i]] = i;
    }
    int padding = data.endsWith('==')
        ? 2
        : data.endsWith('=')
            ? 1
            : 0;
    int length = (data.length * 3 ~/ 4) - padding;
    List<int> result = List<int>.filled(length, 0);

    int resultIndex = 0;
     for (int i = 0; i < data.length; i += 4) {
    final remaining = data.length - i;
    if (remaining < 1) break;

    int sextetA = charMap[data[i]] ?? 0;
    int sextetB = (remaining >= 2) ? charMap[data[i + 1]] ?? 0 : 0;
    int sextetC = (remaining >= 3) ? charMap[data[i + 2]] ?? 0 : 0;
    int sextetD = (remaining >= 4) ? charMap[data[i + 3]] ?? 0 : 0;

    int triple = (sextetA << 18) | (sextetB << 12) | (sextetC << 6) | sextetD;

    if (resultIndex < length) result[resultIndex++] = (triple >> 16) & 0xFF;
    if (resultIndex < length && remaining >= 2) result[resultIndex++] = (triple >> 8) & 0xFF;
    if (resultIndex < length && remaining >= 3) result[resultIndex++] = triple & 0xFF;
  }
    // print('${result}===========result解密后的数据');
    return result;
  }

  // 安全UTF-8解码
  static String _safeUtf8Decode(List<int> bytes) {
    try {
      return utf8.decode(bytes);
    } on FormatException {
      return utf8.decode(bytes, allowMalformed: true);
    }
  }

  // 安全JSON解析
  static dynamic safeJsonParse(String str) {
    dynamic json;
    String currentStr = str;
    while (currentStr.isNotEmpty) {
      try {
        json = jsonDecode(currentStr);
        return json;
      } on FormatException {
        currentStr = currentStr.substring(0, currentStr.length - 1);
      }
    }
    return null;
  }
  
}
